/**
 * @file	
 * @author	chipsea
 * @brief	
 * @version	0.1
 * @date	2020-11-30
 * @copyright Copyright (c) 2020, CHIPSEA Co., Ltd.
 * @note
 */

#ifndef _LL_H_
#define _LL_H_

#include "types.h"
#include "mcu.h"
#include "ll.h"
#include "ll_def.h"
#include "common.h"

#define LL_DATA_PDU( pktHdr )     ((pktHdr) != LL_DATA_PDU_HDR_LLID_CONTROL_PKT)
#define LL_CTRL_PDU( pktHdr )     ((pktHdr) == LL_DATA_PDU_HDR_LLID_CONTROL_PKT)
#define LL_INVALID_LLID( pktHdr ) ((pktHdr) == LL_DATA_PDU_HDR_LLID_RESERVED)

#define LL_TX_PUSH_BYTE(connPtr, dat)	{ \
											connPtr->ll_buf.tx_conn_desc_buf[connPtr->ll_buf.tx_conn_desc_buf_wr] = dat; \
											connPtr->ll_buf.tx_conn_desc_buf_wr++; \
											if(connPtr->ll_buf.tx_conn_desc_buf_wr >= TX_DATA_BUF_LEN) { \
												connPtr->ll_buf.tx_conn_desc_buf_wr = 0; \
											} \
										}

#define LL_TX_WR_ALIGN_DWORD(connPtr)	{ \
											if(connPtr->ll_buf.tx_conn_desc_buf_wr & 0x03) { \
												connPtr->ll_buf.tx_conn_desc_buf_wr += (4-(connPtr->ll_buf.tx_conn_desc_buf_wr & 0x03)); \
											} \
											if(connPtr->ll_buf.tx_conn_desc_buf_wr >= TX_DATA_BUF_LEN) { \
												connPtr->ll_buf.tx_conn_desc_buf_wr = 0; \
											} \
										}


extern struct buf_long_desc ll_buffer;
										
void LL_IRQHandler(void);

void move_to_slave_function(void);

void LL_slave_conn_event(void);

void LL_master_conn_event(void);

void LL_set_default_conn_params(llConnState_t *connPtr);

//void ll_setMem(uint8_t  *buf, uint8_t v, int n);

//void ll_cpyMem(uint8_t *dst, uint8_t *src, int n);

void LL_evt_schedule(void);

//llStatus_t llSetupAdv( void );

void llConvertLstoToEvent( llConnState_t *connPtr,
                           connParam_t   *connParams );

void llSlaveEvt_TaskEndOk( void );

// for master process
void llMasterEvt_TaskEndOk( void );

// Connection Management
extern llConnState_t      *llAllocConnId( void );
extern void               llReleaseConnId( llConnState_t *connPtr );
extern void               llReleaseAllConnId( void );
extern uint16             llGetMinCI( uint16 connInterval );
extern uint8              llGetNextConn( void );
extern void               llConnCleanup( llConnState_t *connPtr );
extern void               llConnTerminate( llConnState_t *connPtr, uint8 reason );
extern uint8              llPendingUpdateParam( void );
extern void               llInitFeatureSet( void );
extern uint32             llGenerateValidAccessAddr( void );
extern uint32             llGenerateCRC( void );
extern  uint8             llEventInRange( uint16 curEvent, uint16 nextEvent, uint16 updateEvent );
extern  uint16            llEventDelta( uint16 eventA, uint16 eventB );
extern void               llConvertLstoToEvent( llConnState_t *connPtr, connParam_t *connParams );
extern void               llConvertCtrlProcTimeoutToEvent( llConnState_t *connPtr );
extern uint8              llAdjustForMissedEvent(llConnState_t *connPtr, uint32 timeToNextEvent);

// Task Setup
extern llStatus_t         llSetupAdv( void );
extern void               llSetupDirectedAdvEvt( void );
extern void               llSetupUndirectedAdvEvt( void );
extern void               llSetupNonConnectableAdvEvt( void );
extern void               llSetupScannableAdvEvt( void );
extern llStatus_t         llSetupScan(uint8 chan);
extern void               llSetupScanInit( void );
extern llStatus_t         llSetupInit(uint8 connId);
extern void               llSetupConn(void);

extern uint32             llCalcMaxScanTime(void);
extern uint8              llSecAdvAllow(void);

extern uint8_t            ll_get_next_active_conn(uint8_t current_conn_id);
extern void               ll_scheduler(uint32 time);

extern void               ll_addTask(uint8 connId, uint32 time);
extern void               ll_deleteTask(uint8 connId);




// Data Management
extern uint8              llEnqueueDataQ( llDataQ_t *pDataQ, txData_t *pTxData );
extern uint8              llEnqueueHeadDataQ( llDataQ_t *pDataQ, txData_t *pTxData );
extern txData_t          *llDequeueDataQ( llDataQ_t *pDataQ );
extern uint8              llDataQEmpty( llDataQ_t *pDataQ );
extern uint8              llWriteTxData ( llConnState_t *connPtr, uint8 pktHdr, uint8 pktLen, uint8 *pBuf );
extern uint8              *llMemCopySrc( uint8 *pDst, uint8 *pSrc, uint8 len );
extern uint8              *llMemCopyDst( uint8 *pDst, uint8 *pSrc, uint8 len );
extern void               llProcessMasterControlPacket( llConnState_t *connPtr, uint8 *pBuf );
extern void               llProcessSlaveControlPacket( llConnState_t *connPtr, uint8 *pBuf );
extern  void              llProcessTxData( llConnState_t *connPtr, uint8 context );
extern  uint8             llProcessRxFIFO(void);

// Control Procedure Setup
extern uint8              llSetupUpdateParamReq( llConnState_t *connPtr );  // M
extern uint8              llSetupUpdateChanReq( llConnState_t *connPtr );   // M
extern uint8              llSetupEncReq( llConnState_t *connPtr );          // M
extern uint8              llSetupEncRsp( llConnState_t *connPtr );          // S
extern uint8              llSetupStartEncReq( llConnState_t *connPtr );     // S
extern uint8              llSetupStartEncRsp( llConnState_t *connPtr );     // M, S
extern uint8              llSetupPauseEncReq( llConnState_t *connPtr );     // M
extern uint8              llSetupPauseEncRsp( llConnState_t *connPtr );     // S
extern uint8              llSetupRejectInd( llConnState_t *connPtr ,uint8 errCode);       // S
extern uint8              llSetupFeatureSetReq( llConnState_t *connPtr );   // M, S
extern uint8              llSetupFeatureSetRsp( llConnState_t *connPtr );   // M, S
extern uint8              llSetupVersionIndReq( llConnState_t *connPtr );   // M
extern uint8              llSetupTermInd( llConnState_t *connPtr );         // M, S
extern uint8              llSetupUnknownRsp( llConnState_t *connPtr );      // M, S

extern uint8              llSetupDataLenghtReq( llConnState_t *connPtr );//M,S
extern uint8              llSetupDataLenghtRsp( llConnState_t *connPtr );//M,S
extern uint8              llSetupPhyReq( llConnState_t *connPtr );          //M,S
extern uint8              llSetupPhyRsp( llConnState_t *connPtr );   //M,S
extern uint8              llSetupPhyUpdateInd( llConnState_t *connPtr );//M
extern uint8              llSetupRejectExtInd( llConnState_t *connPtr ,uint8 errCode);

// Control Procedure Management
extern void               llEnqueueCtrlPkt( llConnState_t *connPtr, uint8 ctrlType );
extern void               llDequeueCtrlPkt( llConnState_t *connPtr );
extern void               llReplaceCtrlPkt( llConnState_t *connPtr, uint8 ctrlType );


// Data Channel Management
extern void               llProcessChanMap( llConnState_t *connPtr, uint8 *chanMap );
extern  uint8    llGetNextDataChan( llConnState_t *connPtr, uint16 numEvents );
extern  void     llSetNextDataChan( llConnState_t *connPtr );
extern uint8              llAtLeastTwoChans( uint8 *chanMap );




uint8_t llTimeCompare(int base_time, int fine_time);
uint32_t calculateTimeDelta(int base_time, int  fine_time);

void llSetNextDataChan( llConnState_t *connPtr );

// White List Related
extern llStatus_t         llCheckWhiteListUsage( void );

// function add by HZF
void llResetConnId(void);
void llResetRfCounters(void);
extern void               llInitFeatureSet( void );


extern  uint16 llCalcScaFactor( uint8 masterSCA );


extern void llCalcTimerDrift( uint32    connInterval,
                                 uint16    slaveLatency,
                                 uint8     sleepClkAccuracy,
                                 uint32 *timerDrift );


// add by HZF
uint8 llGetNextAdvChn(uint8 cur_chn);

uint16_t getTxBufferSize(llConnState_t *connPtr);
uint16_t getTxBufferFree(llConnState_t *connPtr);

// reset buffer
void reset_conn_buf(uint8_t connId);

void ll_schedule_next_event(int time);

uint16 ll_generateTxBuffer(int txFifo_vacancy, uint16 *pSave_ptr);
void ll_hw_read_tfifo_rtlp(void);
int ll_hw_read_tfifo_packet(uint8 *pkt);

// function in ll_slaveEndCause.c
uint8 llSetupNextSlaveEvent( void );
uint8 llProcessSlaveControlProcedures( llConnState_t *connPtr );
uint8 llCheckForLstoDuringSL( llConnState_t *connPtr );

// function in ll_hwItf.c
void ll_hw_process_RTO(uint32 ack_num);
void ll_debug_output(uint32 state);

void llAdjSlaveLatencyValue( llConnState_t *connPtr );

//function for DLE add by ZQ
void llPduLengthManagmentReset(void);
void llTrxNumAdaptiveConfig(void);
void llPduLengthUpdate(uint16 connHandle);

void ll_hw_tx2rx_timing_config(uint8 pkt);

//function for PHY UPDATE add by ZQ
void llPhyModeCtrlReset(void);
void llPhyModeCtrlUpdateNotify(llConnState_t *connPtr, uint8 status);
uint8_t LL_GetLinkRole(uint8_t connId);
void llSetNextPhyMode(llConnState_t *connPtr);
extern void llInitFeatureSetDLE(uint8 enable);
extern void llInitFeatureSet2MPHY(uint8 enable);
extern void llInitFeatureSetCodedPHY(uint8 enable);
extern void llInitFeatureSetCSA2(uint8 enable);

extern uint8_t ll_getBusyLinkNumber(void);
extern uint16_t ll_findConnHandle(uint8 addrType, uint8 addr[]);
extern void ll_processPendingAdvScanCustomRf(void);
extern void ll_restartScan(void);
extern void ll_restartInit(void);



#endif

